<?php

/*
 * Copyright (C) 2009 - 2011 Pham Cong Dinh
 *
 * This file is part of Spica.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 3 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

/**
 * <p>Set of methods to support image manipulation.</p>
 *
 * namespace spica\core\utils\ImageUtils
 *
 * @category   spica
 * @package    core
 * @subpackage utils
 * @author     Pham Cong Dinh <pcdinh at phpvietnam dot net>
 * @since      Version 0.3
 * @since      May 03, 2009
 * @copyright  Pham Cong Dinh (http://www.phpvietnam.net)
 * @license    http://www.gnu.org/licenses/lgpl-3.0.txt
 * @version    $Id: ImageUtils.php 1869 2011-01-07 18:55:25Z pcdinh $
 */
class SpicaImageUtils
{
    /**
     * Creates a new image by resizing the original image but keeps it intact.
     *
     * @example $img = SpicaImageUtils::resize('/path/to/some/image.jpg', 150, 150);
     *
     * @throws  Exception
     * @param   string $file
     * @param   float $width
     * @param   float $height
     * @param   bool $crop
     * @return  resource Image source that can be used with imagejpeg(), imagepng(), imagegif()
     */
    public static function resize($file, $width, $height, $crop = false)
    {
        list($originalWidth, $originalHeight) = getimagesize($file);
        $ratio   = $originalWidth / $originalHeight;

        if (true === $crop)
        {
            if ($originalWidth > $originalHeight)
            {
                $originalWidth  = ceil($originalWidth - ($originalWidth*($ratio - $width/$height)));
            }
            else
            {
                $originalHeight = ceil($originalHeight - ($originalHeight*($ratio - $width/$height)));
            }

            $newWidth  = $width;
            $newHeight = $height;
        }
        else
        {
            if ($width/$height > $ratio)
            {
                $newWidth  = $height*$ratio;
                $newHeight = $height;
            }
            else
            {
                $newHeight = $width/$ratio;
                $newWidth  = $width;
            }
        }

        $lastDot  = strrpos($file, '.');

        if (false === $lastDot)
        {
            throw new Exception('This file has no extension that is required to detect what kind of image it is. ');
        }

        $ext = substr($file, $lastDot + 1);

        switch ($ext)
        {
            case 'jpg':
                $src = imagecreatefromjpeg($file);
                break;

            case 'png':
                $src = imagecreatefrompng($file);
                break;

            case 'gif':
                $src = imagecreatefromgif($file);
                break;

            default:
                $src = imagecreatefromgd2($file);
                break;
        }

        if (false === $src)
        {
            throw new Exception('Unable to create a new image from the source. ');
        }

        $image = imagecreatetruecolor($newWidth, $newHeight);
        imagecopyresampled($image, $src, 0, 0, 0, 0, $newWidth, $newHeight, $originalWidth, $originalHeight);
        imagedestroy($src);
        return $image;
    }

    /**
     * Saves an image resource to a file.
     * 
     * @param resource $image
     * @param string $filePath
     * @param int $quality
     */
    public static function saveTo($image, $filePath, $quality = 100)
    {
        imagejpeg($image, $filePath, $quality);
        imagedestroy($image);
    }

    /**
     * Resizes an image and saves the image with new dimensions into a new file.
     *
     * @param string $file
     * @param int $width
     * @param int $height
     * @param string $filePath
     * @param bool $crop
     * @param int $quality
     */
    public static function resizeTo($file, $width, $height, $filePath, $crop = false, $quality = 100)
    {
        self::saveTo(self::resize($file, $width, $height, $crop), $filePath, $quality);
    }
}

?>